---
title: useUIState
layout:
  toc: false
---

import { Tabs, Tab } from 'nextra-theme-docs';

# useUIState

## `useUIState`

`useUIState` is a hook that enables you to read and update the [UI State](/docs/concepts/ai-rsc#uistate) of your `ai/rsc` instance.
The state is client-side and can contain functions, React nodes, and other data. `UIState` is the visual representation of the [AI state](/docs/concepts/ai-rsc#state).

<Tabs items={['Next.js (App Router)']}>
  <Tab>
    `useUIState` behaves like `useState`, exposing the UI state (`messages`) and the update function (`setMessages`) into your application.
    In the case of a chat application, your UI state might contain an array of messages, each with a `display` property that contains a React node and an `id` property that is a unique identifier.
    The ID is useful in case you want to update or delete a message / member of the state.

    ```tsx filename="app/page.tsx" {4, 9-13, 17-23}
    import { useUIState } from "ai/rsc";

    export default function Page() {
      const [messages, setMessages] = useUIState();
      const [inputValue, setInputValue] = useState("");

      return (
        <div>
          {messages.map((message) => (
            <div key={message.id}>
              {message.display}
            </div>
          ))}

          <form
            onSubmit={async (event: any) => {
              setMessages((currentMessages) => [
                ...currentMessages,
                {
                  id: Date.now(),
                  display: <UserMessage>{value}</UserMessage>,
                },
              ]);
            }}
          >
            <input
              placeholder="Type a message..."
              autoFocus
              value={inputValue}
              onChange={(event) => setInputValue(event.target.value)}
            />
          </form>
        </div>
      );
    }
    ```

  </Tab>
</Tabs>
